import time
from django.conf import settings
from rest_framework.exceptions import ValidationError
from rest_framework import serializers

from .models import ShoppingCart, OrderInfo, OrderGoods
from goods.serializers import GoodsSerializer
from goods.models import Goods
from WorkBookShop.utils.al_pay import alipay, gateway


class ShopCartDetailSerializer(serializers.ModelSerializer):
    # 一条购物车关系记录对应的只有一个goods。
    goods = GoodsSerializer(many=False, read_only=True)

    class Meta:
        model = ShoppingCart
        fields = ("goods", "nums")


class ShopCartSerializer(serializers.Serializer):
    # 使用Serializer本身最好, 因为它是灵活性最高的。
    user = serializers.HiddenField(
        default=serializers.CurrentUserDefault()
    )
    nums = serializers.IntegerField(required=True, label="数量", min_value=1,
                                    error_messages={
                                        "min_value": "商品数量不能小于一",
                                        "required": "请选择购买数量"
                                    })
    goods = serializers.PrimaryKeyRelatedField(required=True, queryset=Goods.objects.all())

    def create(self, validated_data):
        user = self.context["request"].user
        nums = validated_data["nums"]
        goods = validated_data["goods"]

        existed = ShoppingCart.objects.filter(user=user, goods=goods)

        if existed:
            existed = existed[0]
            existed.nums += nums
            existed.save()
        else:
            existed = ShoppingCart.objects.create(**validated_data)

        return existed

    def update(self, instance, validated_data):
        # 修改商品数量
        instance.nums = validated_data["nums"]
        instance.save()
        return instance


class OrderGoodsSerialzier(serializers.ModelSerializer):
    goods = GoodsSerializer(many=False)

    class Meta:
        model = OrderGoods
        fields = "__all__"


class OrderSerializer(serializers.ModelSerializer):
    user = serializers.HiddenField(
        default=serializers.CurrentUserDefault()
    )

    pay_status = serializers.CharField(read_only=True)
    trade_no = serializers.CharField(read_only=True)
    order_sn = serializers.CharField(read_only=True)
    pay_time = serializers.DateTimeField(read_only=True)

    alipay_url = serializers.SerializerMethodField(read_only=True)
    # alipay_url = serializers.CharField(read_only=True)
    # def get_alipay_url(self, obj):
    #     alipay = AliPay(
    #         appid="2016101600697605",
    #         # app_notify_url="http://vueshop.mtianyan.cn/alipay/return/",
    #         app_notify_url='https://www.baidu.com/',
    #         app_private_key_path=private_key_path,
    #         alipay_public_key_path=ali_pub_key_path,  # 支付宝的公钥，验证支付宝回传消息使用，不是你自己的公钥,
    #         # debug=True,  # 默认False,
    #         # return_url="http://vueshop.mtianyan.cn/alipay/return/",
    #         return_url="https://www.baidu.com/"
    #     )
    #
    #     url = alipay.direct_pay(
    #         subject=obj.order_sn,
    #         out_trade_no=obj.order_sn,
    #         total_amount=obj.order_mount,
    #     )
    #     # re_url = "https://openapi.alipay.com/gateway.do?{data}".format(data=url)
    #     re_url = "https://openapi.alipaydev.com/gateway.do?{data}".format(data=url)
    #
    #     return re_url

    def get_alipay_url(self, obj):

        return self.context.get('alipay_url', None)
        # url = alipay.api_alipay_trade_page_pay(
        #     out_trade_no=obj.order_sn,  # 商家生成的订单号 *
        #     total_amount=obj.order_mount,  # 88元 *
        #     subject=obj.order_sn,  # 订单名字 *
        #     return_url=settings.RETURN_URL,  # 成功后回调地址（get回调） *
        #     notify_url=settings.APP_NOTIFY_URL  # this is optional  # # 可选, 不填则使用默认notify url, 成功后回调地址（post回调） *
        # )
        #
        # re_url = "{gateway}?{data}".format(gateway=gateway, data=url)
        # return re_url

    def _generate_order_sn(self):  # 订单号 ok
        # 当前时间+userid+随机数(两位)
        from random import Random
        random_ins = Random()
        order_sn = "{time_str}{userid}{ranstr}".format(time_str=time.strftime("%Y%m%d%H%M%S"),
                                                       userid=self.context["request"].user.id,
                                                       ranstr=random_ins.randint(10, 99))

        return order_sn

    def _check_price(self, attrs):  # 1.订单价格校验
        total_amount = attrs.get('order_mount')
        shop_cars = ShoppingCart.objects.filter(user=self.context["request"].user)
        total_price = 0
        for shop_car in shop_cars:
            total_price += shop_car.goods.shop_price * shop_car.nums  # 单件商品*数量
        if total_amount != total_price:
            raise ValidationError('价格不合法')
        return total_amount

    def _get_user(self):
        return self.context.get('request')

    def _gen_pay_url(self, order_sn, total_amount):
        url = alipay.api_alipay_trade_page_pay(
            out_trade_no=order_sn,  # 商家生成的订单号 *
            total_amount=total_amount,  # 88元 *
            subject=order_sn,  # 订单名字 *
            return_url=settings.RETURN_URL,  # 成功后回调地址（get回调） *
            notify_url=settings.APP_NOTIFY_URL  # this is optional  # # 可选, 不填则使用默认notify url, 成功后回调地址（post回调） *
        )

        re_url = "{gateway}?{data}".format(gateway=gateway, data=url)
        return re_url

    # 入库前准备
    def _before_create(self, attrs, user):
        # attrs['user'] = user
        pass

    def validate(self, attrs):  # 订单号
        """
        1.订单价格校验
        2.生成订单号
        3.支付用户
        4.支付链接生成
        5.入库（两个表）的信息准备
        """
        total_amount = self._check_price(attrs)
        attrs["order_sn"] = self._generate_order_sn()  # 202101020238032762
        user = self._get_user()
        re_url = self._gen_pay_url(attrs["order_sn"], total_amount)

        #  把返回的alipay url 保存到context中，然后在get_alipay_url拿出此url并return
        self.context['alipay_url'] = re_url
        self._before_create(attrs, user)

        return attrs

    def create(self, validated_data):
        return super(OrderSerializer, self).create(validated_data)

    class Meta:
        model = OrderInfo
        fields = "__all__"


class OrderDetailSerializer(serializers.ModelSerializer):
    # 一个订单有多个订单商品项

    goods = OrderGoodsSerialzier(many=True)

    alipay_url = serializers.SerializerMethodField(read_only=True)

    def get_alipay_url(self, obj):

        url = alipay.api_alipay_trade_page_pay(
            out_trade_no=obj.order_sn,  # 商家生成的订单号 *
            total_amount=obj.order_mount,  # 88元 *
            subject=obj.order_sn,  # 订单名字 *
            return_url=settings.RETURN_URL,  # 成功后回调地址（get回调） *
            notify_url=settings.APP_NOTIFY_URL  # this is optional  # # 可选, 不填则使用默认notify url, 成功后回调地址（post回调） *
        )

        re_url = "{gateway}?{data}".format(gateway=gateway, data=url)
        return re_url

    class Meta:
        model = OrderInfo
        fields = "__all__"

